/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.escom.healthlc.controller;

import com.escom.healthlc.business.ReporteBusiness;
import com.escom.healthlc.entidad.EcgORM;
import com.escom.healthlc.entidad.EstudioORM;
import com.escom.healthlc.entidad.OximetroORM;
import com.escom.healthlc.entidad.PacienteVO;
import com.escom.healthlc.entidad.PersonaVO;
import com.escom.healthlc.entidad.ReporteGraficaVO;
import com.escom.healthlc.entidad.ReporteVO;
import com.escom.healthlc.utils.Constantes;
import java.io.IOException;
import java.io.*;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Carlos
 */
@ManagedBean(name = "ReporteController")
@ViewScoped
public class ReporteController {

    private static final Logger logger = LoggerFactory.getLogger(ReporteController.class);

    @ManagedProperty("#{ReporteBusiness}")
    private ReporteBusiness reporteBusiness;

    private PacienteVO pacienteReporte;
    private String tipoArrimiaString;
    private List<ReporteGraficaVO> reporteGraficaSano;
    private List<ReporteGraficaVO> reporteGraficaTaquicardia;
    private List<ReporteGraficaVO> reporteGraficaBradicardia;
    private List<ReporteGraficaVO> reporteGraficaFibrilacion;
//    private List<Double> segmentoArritmia;
//    private List<Integer> xLine;

    @PostConstruct
    private void initReporteController() {
        executeLimpiarObejects(null);
    }

    public void executeCrearReporte(ActionEvent acEvt) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        ReporteVO consultarPaciente = reporteBusiness.consultarPaciente(pacienteReporte);
        if (consultarPaciente != null && consultarPaciente.getArchivoPrueba() != null && !consultarPaciente.getArchivoPrueba().equals("")) {
            consultarPaciente.setNombrePaciente(consultarPaciente.getNombrePaciente() + " " + consultarPaciente.getApPaternoPaciente() + " " + consultarPaciente.getApMaternoPaciente());
            consultarPaciente.setNombreMedico(consultarPaciente.getNombreMedico() + " " + consultarPaciente.getApPaternoMedico() + " " + consultarPaciente.getApMaternoMedico());
            String archivoPrueba = consultarPaciente.getArchivoPrueba();
            try {
                ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(new File(Constantes.PATH_WEB_VIRTUAL + "\\" + archivoPrueba + ".txt")));
                EstudioORM readObject = (EstudioORM) objectInputStream.readObject();
                String[] mediaOximetro = reporteBusiness.obtenerMediaOximetro(readObject.getOximetros());
                String temperatura = reporteBusiness.obtenerMediaTemperatura(readObject.getTemperaturas());
                List<EcgORM> arritmias = readObject.getArritmias();
                obtenerSegmento(arritmias);
                consultarPaciente.setTemperatura(temperatura);
                consultarPaciente.setOxigeno(mediaOximetro[0]);
                consultarPaciente.setPulsaciones(mediaOximetro[1]);
//                consultarPaciente.setSegmentoArritmia(segmentoArritmia);
                consultarPaciente.setTipoArritmia(tipoArrimiaString);
                consultarPaciente.setSanoElectrocadiograma(reporteGraficaSano);
                consultarPaciente.setTaquicardiaElectrocadiograma(reporteGraficaTaquicardia);
                consultarPaciente.setBradicardiaElectrocadiograma(reporteGraficaBradicardia);
                consultarPaciente.setFibrilacionElectrocadiograma(reporteGraficaFibrilacion);
//                consultarPaciente.setxLine(xLine);
//                consultarPaciente.setTitleSerie("Electrocadiograma");
                exportarPDF(consultarPaciente);
            } catch (FileNotFoundException ex) {
//                logger.error("Error Logger : {}", ex.getCause().getMessage());
                logger.error("Error Logger : {}", ex.fillInStackTrace().toString());
            } catch (IOException ex) {
//                logger.error("Error Logger : {}", ex.getCause().getMessage());
                logger.error("Error Logger : {}", ex.fillInStackTrace().toString());
            } catch (ClassNotFoundException ex) {
//                logger.error("Error Logger : {}", ex.getCause().getMessage());
                logger.error("Error Logger : {}", ex.fillInStackTrace().toString());
            }
        } else {
            facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, Constantes.MESSAGE_TITLE, "No existe aún reporte asociado al nombre ingresado.");
            facesContext.addMessage(null, facesMessage);
        }
    }

    public void exportarPDF(ReporteVO consultarPaciente) {
        try {
            Collection<ReporteVO> entidad = new ArrayList<ReporteVO>();
            entidad.add(consultarPaciente);
            String fileName = consultarPaciente.getNombrePaciente();
            JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(entidad);
            String reportPath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/resources/reports/ReportePaciente.jasper");
            JasperPrint jasperPrint;
            jasperPrint = JasperFillManager.fillReport(reportPath, new HashMap(), beanCollectionDataSource);
            HttpServletResponse httpServletResponse = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
            httpServletResponse.addHeader("Content-disposition", "attachment; filename=" + fileName + " Reporte Medico.pdf");
            ServletOutputStream servletOutputStream = httpServletResponse.getOutputStream();

            JRExporter exporter = new JRPdfExporter();
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
            exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, servletOutputStream); // your output goes here

            exporter.exportReport();
            FacesContext.getCurrentInstance().responseComplete();
        } catch (JRException ex) {
            logger.error("Logger Error: {}", ex.getCause().getMessage());
            logger.error("Logger Error: {}", ex.fillInStackTrace().toString());
        } catch (IOException ex) {
            logger.error("Logger Error: {}", ex.getCause().getMessage());
            logger.error("Logger Error: {}", ex.fillInStackTrace().toString());
        }
    }

    public void obtenerSegmento(List<EcgORM> arritmias) {
        tipoArrimiaString = "";
        reporteGraficaSano = new ArrayList<>();
        reporteGraficaTaquicardia = new ArrayList<>();
        reporteGraficaBradicardia = new ArrayList<>();
        reporteGraficaFibrilacion = new ArrayList<>();
        String taquicardia = "", bradicardia = "", fibrilacionAuricular = "";
        for (int i = 0; i < arritmias.size(); i++) {
            ReporteGraficaVO tickGrafica = new ReporteGraficaVO();
            EcgORM arritmia = arritmias.get(i);
            double value = Double.parseDouble(arritmia.getValue());
            int tipoArritmia = Integer.parseInt(arritmia.getTipoArritmia());
            switch (tipoArritmia) {
                case 0:
                    taquicardia = "Taquicardia";
                    tickGrafica.setGrafica(taquicardia);
                    tickGrafica.setxValue(i);
                    tickGrafica.setyValue(value);
                    if (reporteGraficaSano.size() < 100) {
                        reporteGraficaSano.add(tickGrafica);
                    }
                    break;
                case 1:
                    taquicardia = "Taquicardia";
                    tickGrafica.setGrafica(taquicardia);
                    tickGrafica.setxValue(i);
                    tickGrafica.setyValue(value);
                    if (reporteGraficaTaquicardia.size() < 100) {
                        reporteGraficaTaquicardia.add(tickGrafica);
                    }
                    break;
                case 2:
                    bradicardia = "Bradicardia";
                    tickGrafica.setGrafica(bradicardia);
                    tickGrafica.setxValue(i);
                    tickGrafica.setyValue(value);
                    if (reporteGraficaBradicardia.size() < 100) {
                        reporteGraficaBradicardia.add(tickGrafica);
                    }
                    break;
                case 3:
                    fibrilacionAuricular = "Fibrilacion Auricular";
                    tickGrafica.setGrafica(fibrilacionAuricular);
                    tickGrafica.setxValue(i);
                    tickGrafica.setyValue(value);
                    if (reporteGraficaFibrilacion.size() < 100) {
                        reporteGraficaFibrilacion.add(tickGrafica);
                    }
                    break;
            }
        }
        tipoArrimiaString = taquicardia + " " + bradicardia + " " + fibrilacionAuricular;
        logger.debug("TipoArritmia {}", tipoArrimiaString);
    }

    public void executeLimpiarObejects(ActionEvent acEvt) {
        pacienteReporte = new PacienteVO();
    }

    public void setReporteBusiness(ReporteBusiness reporteBusiness) {
        this.reporteBusiness = reporteBusiness;
    }

    public PacienteVO getPacienteReporte() {
        return pacienteReporte;
    }

    public void setPacienteReporte(PacienteVO pacienteReporte) {
        this.pacienteReporte = pacienteReporte;
    }

}
